﻿using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LockDemo.Attributes
{ 
    public class DistributedLockFilterAttribute : Attribute, IAsyncActionFilter
    {
        private readonly string _lockPrefix;
        private readonly LockType _lockType;

        public DistributedLockFilterAttribute(string keyPrefix, LockType lockType = LockType.Local)
        {
            _lockPrefix = keyPrefix;
            _lockType = lockType;
        }

        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            IDistributedLock distributedLock = context.HttpContext.RequestServices.GetRequiredKeyedService<IDistributedLock>(_lockType.GetDescription());

            string controllerName = context.RouteData.Values["controller"]?.ToString() ?? "";
            string actionName = context.RouteData.Values["action"]?.ToString() ?? "";
            //用户信息或其他唯一标识都可
            var userKey = context.HttpContext.User!.Identity!.Name;

            string lockKey = $"{_lockPrefix}:{userKey}:{controllerName}_{actionName}";
            bool isLockAcquired = await distributedLock.TryAcquireLockAsync(lockKey);

            if (!isLockAcquired)
            {
                context.Result = new Microsoft.AspNetCore.Mvc.ObjectResult(new { code = 400, message = "请不要重复操作" });
                return;
            }

            try
            {
                await next();
            }
            finally
            {
                await distributedLock.ReleaseLockAsync(lockKey);
            }
        }
    }
}
